﻿using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using System.Collections.Generic;

namespace ChangDiTools
{
    public static class BlockTool
    {
        /// <summary>
        /// 将块添加到数据库
        /// </summary>
        /// <param name="db"></param>
        /// <param name="btrName"></param>
        /// <param name="ents"></param>
        /// <returns></returns>
        public static ObjectId AddBlockTableRecord(this Database db, string btrName, List<Entity> ents)
        {
            ObjectId btrId = ObjectId.Null;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                if (!bt.Has(btrName))
                {
                    BlockTableRecord btr = new BlockTableRecord
                    {
                        Name = btrName
                    };
                    foreach (Entity ent in ents)
                    {
                        btr.AppendEntity(ent);
                    }
                    bt.UpgradeOpen();
                    bt.Add(btr);
                    tr.AddNewlyCreatedDBObject(btr, true);
                    bt.DowngradeOpen();
                }

                btrId = bt[btrName];
                tr.Commit();
            }

            return btrId;
        }
        /// <summary>
        /// 插入块
        /// </summary>
        /// <param name="db"></param>
        /// <param name="blockRecordId"></param>
        /// <param name="pt"></param>
        /// <returns></returns>
        public static ObjectId InsterBlockReference(this Database db, ObjectId blockRecordId, Point3d pt)
        {
            ObjectId brId = ObjectId.Null;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                if (bt.Has(blockRecordId))
                {
                    BlockReference br = new BlockReference(pt, blockRecordId);
                    BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
                    brId = btr.AppendEntity(br);
                    tr.AddNewlyCreatedDBObject(br, true);
                }
                tr.Commit();
            }
            return brId;
        }
        /// <summary>
        /// 插入参照块
        /// </summary>
        /// <param name="db"></param>
        /// <param name="blockRecordId"></param>
        /// <param name="pt"></param>
        /// <param name="ang"></param>
        /// <returns></returns>
        public static ObjectId InsterAttrBlockReference(this Database db, ObjectId blockRecordId, Point3d pt, double ang)
        {
            ObjectId brId = ObjectId.Null;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                if (bt.Has(blockRecordId))
                {
                    Tools.AddLayer("0DL-05道路坡度", 3);
                    //声明块参照
                    BlockReference br = new BlockReference(pt, blockRecordId)
                    {
                        Rotation = ang
                    };
                    BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
                    brId = btr.AppendEntity(br);
                    //添加定义属性
                    BlockTableRecord blockRecord = blockRecordId.GetObject(OpenMode.ForRead) as BlockTableRecord;
                    if (blockRecord.HasAttributeDefinitions)
                    {
                        foreach (ObjectId item in blockRecord)
                        {
                            DBObject obj = item.GetObject(OpenMode.ForRead);
                            if (obj is AttributeDefinition)
                            {
                                AttributeReference attrRef = new AttributeReference();
                                attrRef.SetAttributeFromBlock((AttributeDefinition)obj, br.BlockTransform);
                                br.AttributeCollection.AppendAttribute(attrRef);
                                tr.AddNewlyCreatedDBObject(attrRef, true);
                            }
                        }
                    }
                    tr.AddNewlyCreatedDBObject(br, true);
                }
                tr.Commit();
            }
            return brId;
        }
        /// <summary>
        /// 更新块参照的属性
        /// </summary>
        /// <param name="BlockRefId"></param>
        /// <param name="attrName"></param>
        public static void UpdateBlockAttr(this ObjectId BlockRefId, Dictionary<string, string> attrName)
        {
            using (Transaction tr = BlockRefId.Database.TransactionManager.StartTransaction())
            {
                if (BlockRefId != ObjectId.Null)
                {
                    BlockReference br = BlockRefId.GetObject(OpenMode.ForRead) as BlockReference;
                    foreach (ObjectId item in br.AttributeCollection)
                    {
                        AttributeReference attRef = item.GetObject(OpenMode.ForRead) as AttributeReference;
                        if (attrName.ContainsKey(attRef.Tag.ToString()))
                        {
                            attRef.UpgradeOpen();
                            attRef.TextString = attrName[attRef.Tag.ToString()].ToString();
                            attRef.DowngradeOpen();
                        }
                    }
                }
                tr.Commit();
            }
        }
    }

    /// <summary>
    /// 用来定义块
    /// </summary>
    public static class MyBlockTableRecord
    {
        private static string blockName = "Block";
        public static string BlockName { get => blockName; set => blockName = value; }

        private static List<Entity> blockEntities = new List<Entity>();
        public static List<Entity> BlockEntities {
            get {
                Circle circle = new Circle(Point3d.Origin, Vector3d.ZAxis, 5);
                Line line1 = new Line(new Point3d(-5, 0, 0), new Point3d(5, 0, 0));
                Line line2 = new Line(new Point3d(0, 5, 0), new Point3d(0, -5, 0));
                blockEntities.Add(circle);
                blockEntities.Add(line1);
                blockEntities.Add(line2);
                return MyBlockTableRecord.blockEntities;
            }
        }

        private static ObjectId blockId1 = ObjectId.Null;
        public static ObjectId BlockId1 { get => blockId1; set => blockId1 = value; }



        private static string attrBlockName = "DL-PDPC";
        public static string AttrBlockName { get => attrBlockName; set => attrBlockName = value; }

        private static List<Entity> attrBlockEntities = new List<Entity>();
        public static List<Entity> AttrBlockEntities {
            get {
                Tools.AddLayer("0DL-05道路坡度", 3);
                Polyline pl = new Polyline();
                Point2d p1 = new Point2d(-3, 0);
                Point2d p2 = new Point2d(3, 0);
                Point2d p3 = new Point2d(5.5, 0);
                pl.AddVertexAt(0, p1, 0, 0.2, 0.2);
                pl.AddVertexAt(1, p2, 0, 0.8, 0);
                pl.AddVertexAt(2, p3, 0, 0, 0);
                AttributeDefinition attr = new AttributeDefinition
                {
                    Tag = "DLPD",
                    Prompt = "道路坡度",
                    TextString = "0.30%",
                    Height = 1.6,
                    WidthFactor = 0.8,
                    HorizontalMode = TextHorizontalMode.TextCenter,
                    VerticalMode = TextVerticalMode.TextBottom,
                    Position = new Point3d(0, 0.1, 0)
                };
                attr.AlignmentPoint = attr.Position;
                AttributeDefinition attr2 = new AttributeDefinition
                {
                    Tag = "DLCD",
                    Prompt = "道路长度",
                    TextString = "40.00",
                    Height = 1.6,
                    WidthFactor = 0.8,
                    HorizontalMode = TextHorizontalMode.TextCenter,
                    VerticalMode = TextVerticalMode.TextTop,
                    Position = new Point3d(0, -0.4, 0)
                };
                attr2.AlignmentPoint = attr2.Position;
                attrBlockEntities.Add(pl);
                attrBlockEntities.Add(attr);
                attrBlockEntities.Add(attr2);
                return MyBlockTableRecord.attrBlockEntities;
            }
        }

        private static ObjectId attrBlockId = ObjectId.Null;
        public static ObjectId AttrBlockId { get => attrBlockId; set => attrBlockId = value; }


        private static string attrBlockName2 = "DL-PDPC2";
        public static string AttrBlockName2 { get => attrBlockName2; set => attrBlockName2 = value; }

        private static List<Entity> attrBlockEntities2 = new List<Entity>();
        public static List<Entity> AttrBlockEntities2 {
            get {
                Tools.AddLayer("0DL-05道路坡度", 3);
                Polyline pl = new Polyline();
                Point2d p1 = new Point2d(3, 0);
                Point2d p2 = new Point2d(-3, 0);
                Point2d p3 = new Point2d(-5.5, 0);
                pl.AddVertexAt(0, p1, 0, 0.2, 0.2);
                pl.AddVertexAt(1, p2, 0, 0.8, 0);
                pl.AddVertexAt(2, p3, 0, 0, 0);
                AttributeDefinition attr = new AttributeDefinition
                {
                    Tag = "DLPD",
                    Prompt = "道路坡度",
                    TextString = "0.30%",
                    Height = 1.6,
                    WidthFactor = 0.8,
                    HorizontalMode = TextHorizontalMode.TextCenter,
                    VerticalMode = TextVerticalMode.TextBottom,
                    Position = new Point3d(0, 0.1, 0)
                };
                attr.AlignmentPoint = attr.Position;
                AttributeDefinition attr2 = new AttributeDefinition
                {
                    Tag = "DLCD",
                    Prompt = "道路长度",
                    TextString = "40.00",
                    Height = 1.6,
                    WidthFactor = 0.8,
                    HorizontalMode = TextHorizontalMode.TextCenter,
                    VerticalMode = TextVerticalMode.TextTop,
                    Position = new Point3d(0, -0.4, 0)
                };
                attr2.AlignmentPoint = attr2.Position;
                attrBlockEntities2.Add(pl);
                attrBlockEntities2.Add(attr);
                attrBlockEntities2.Add(attr2);
                return MyBlockTableRecord.attrBlockEntities2;
            }
        }

        private static ObjectId attrBlockId2 = ObjectId.Null;
        public static ObjectId AttrBlockId2 { get => attrBlockId2; set => attrBlockId2 = value; }
    }
}


